import React from "react";
import { Renderer } from "@k8slens/extensions";

//自定义窗口样式
import "./events-llm-explain-dialog.scss";

const {
  Component: { Dialog, Wizard, WizardStep, Button, Input },
} = Renderer;
import { makeObservable, observable } from "mobx";
import { observer } from "mobx-react";
import type { IComputedValue } from "mobx";
import { llmPreferenceStore } from "../../llm/preference/llm-preference-store";
import { HumanMessage, SystemMessage } from "@langchain/core/messages";

import { getStream } from "../../llm/model/llm-model";

import ReactMarkdown from 'react-markdown'

export interface EventsLLMExplainDialogProps {
  isDialogOpen: IComputedValue<boolean>;
}

export const eventsLLMExplainDialogState = observable.object({
  //是否打开窗口弹出
  isOpen: observable.box(false),
  answer: observable.box(""),
  history: observable.array<SystemMessage | HumanMessage>([]),
  answers: observable.array<string>([]),
  step: observable.box(0),
  question: observable.box(""),
  isLoading: observable.box(false),
});

@observer
export class EventsLLMExplainDialog extends React.Component<EventsLLMExplainDialogProps> {
  constructor(props: EventsLLMExplainDialogProps) {
    super(props);
    //接收变量的变化
    makeObservable(this);
  }

  //关闭菜单
  close() {
    eventsLLMExplainDialogState.isOpen.set(false);
  }

  async explainEventByLLMAfter() {
    if (!llmPreferenceStore.apiKey || llmPreferenceStore.apiKey.trim() == "") {
      alert("Please set your api key in LLM Preference");
      return;
    }
    if (!llmPreferenceStore.model || llmPreferenceStore.model.trim() == "") {
      alert("Please set your model in LLM Preference");
      return;
    }
    if (
      !llmPreferenceStore.baseURL ||
      llmPreferenceStore.baseURL.trim() == ""
    ) {
      alert("Please set your baseURL in LLM Preference");
      return;
    }

    eventsLLMExplainDialogState.answer.set("");
    eventsLLMExplainDialogState.isLoading.set(true);

    const messages = eventsLLMExplainDialogState.history.map(
      (message) => message
    );
    messages.push(new HumanMessage(eventsLLMExplainDialogState.question.get()));
    eventsLLMExplainDialogState.answers.push(
      "Ask:" + eventsLLMExplainDialogState.question.get()
    );

    try {
      const stream = await getStream(messages);
      const chunks: string[] = [];
      for await (const chunk of stream) {
        if (Array.isArray(chunk)) {
          for (const c of chunk) {
            if (c.content && !c.tool_call_id) {
              chunks.push(c.content.toString());
              eventsLLMExplainDialogState.answer.set(chunks.join(""));
            }
          }
        } else {
          if (chunk.content && !chunk.ctool_call_id ) {
            chunks.push(chunk.content.toString());
            eventsLLMExplainDialogState.answer.set(chunks.join(""));
          }
        }
      }

      eventsLLMExplainDialogState.step.set(
        eventsLLMExplainDialogState.step.get() + 1
      );
      eventsLLMExplainDialogState.history.push(
        new SystemMessage(chunks.join(""))
      );
      eventsLLMExplainDialogState.answers.push(chunks.join(""));
    } catch (err) {
      console.log(err);
      alert(err);
    }
    eventsLLMExplainDialogState.isLoading.set(false);
  }

  render() {
    const { ...dialogProps } = this.props;

    const  themeName = Renderer.Theme.activeTheme.get().name;
    const header = (
      <span>
        LLM Explain
        <Button
          plain
          onClick={() => {
            eventsLLMExplainDialogState.isOpen.set(false);
          }}
        >
          Close
        </Button>
      </span>
    );

    return (
      <Dialog
        {...dialogProps}
        className={"EventsLLMExplainDialog"+themeName}
        isOpen={this.props.isDialogOpen.get()}
        close={this.close}
      >
        <Wizard header={header} done={this.close}>
          <WizardStep
            disabledNext={true}
            customButtons={
              <div className="buttons flex gaps align-center justify-space-between">
                <Button
                  plain
                  onClick={() => {
                    eventsLLMExplainDialogState.isOpen.set(false);
                  }}
                >
                  Close
                </Button>
              </div>
            }
          >
            {eventsLLMExplainDialogState.answers.map((answer, _index) => {
              return (
                <section>
                  <ReactMarkdown>{answer}</ReactMarkdown>
                  <span>
                    ----------------------------------------------------
                  </span>
                </section>
              );
            })}

            {eventsLLMExplainDialogState.isLoading.get() && (
              <p>
                <ReactMarkdown>{eventsLLMExplainDialogState.answer.get()}</ReactMarkdown>
              </p>
            )}
            {!eventsLLMExplainDialogState.isLoading.get() &&
              eventsLLMExplainDialogState.step.get() > 0 && (
              <table>
                <tr>
                  <td>
                    <Input
                      type="text"
                      style={{ width: "300px" }}
                      value={eventsLLMExplainDialogState.question.get()}
                      onChange={(v) => {
                        eventsLLMExplainDialogState.question.set(v);
                      }}
                    ></Input>
                  </td>
                  <td>
                    <Button
                      plain
                      onClick={async () => {
                        console.log(
                          "question",
                          eventsLLMExplainDialogState.question.get()
                        );
                        await this.explainEventByLLMAfter();
                      }}
                    >
                        Ask
                    </Button>
                  </td>
                </tr>
              </table>
            )}
          </WizardStep>
        </Wizard>
      </Dialog>
    );
  }
}
